"""
网格交易 - 策略示例

策略逻辑:
1. 当价格上涨超过阈值时买入
2. 当价格下跌超过阈值时卖出
3. 基于精确的 strategy_id 控制
"""
import logging
import asyncio
from math import log
import re
from core.base_strategy import BaseStrategy
from typing import Dict, Any


logger = logging.getLogger("GridTradingStrategy")

class GridTradingStrategy(BaseStrategy):
    """网格波段策略"""
    
    async def on_init(self):
        """策略初始化"""
        # 获取参数，设置默认值
        self.symbol = self.params.get("symbol", "SZ000001")


        #TODO 需要获取当前的价格作为基准价  如果不存在则需要获取

        #系统默认基准价格
        self.base_price = float(self.params.get("base_price", 1))  # 系统默认基准价格

        #设置范围区间，防止越界超卖超买
        self.un_price = float(self.params.get("un_price", 0.5))  # 价格区间起始价格
        self.up_price = float(self.params.get("up_price", 10))  # 价格区间结束价格

        #每次交易多少手
        self.sell_size = int(self.params.get("sell_size", 1000))  # 卖出多少股
        self.purchase_size = int(self.params.get("purchase_size", 1000))  # 购买多少股


        #单笔交易步长是多少
        self.sell_step_length = float(self.params.get("sell_step_length", 0.001))  # 卖出步长
        self.purchaseend_step_length = float(self.params.get("purchaseend_step_length",  0.001))  # 购买步长



        # 上下跌的时候 默认连续买多少手 则自动停止 必须等反之过来交易1手才从0计算
        self.continuous_sell_number = int(self.params.get("continuous_sell_number", 3))  # 连续卖出次数就暂停
        self.continuous_purchase_number = int(self.params.get("continuous_purchase_number", 3))  # 连续购买次数就暂停

        #系统变量 当前连续购买跟连续卖出阀值  操作一边后 那么反向的值需要清0
        self.sell_threshold=0
        self.purchase_threshold=0

        #这个策略必须内部单线程 一旦进入则加锁 委托状态。下单成功就是委托成功
        self.entrusted_status=False


        # 订阅行情
        await self.subscribe(self.symbol)
        # 初始化持仓
        self.last_price = None
        logger.info(f"🎯 网格策略初始化完成: {self.symbol},基准价: {self.base_price:.2f}, 买卖范围: {self.un_price:.2f}--{self.up_price:.2f},购买步长: {self.sell_step_length:.2f}，{self.purchaseend_step_length:.2f}，")
    


    async def on_tick(self, data: Dict[str, Any]):
        """有一个初始化范围值"""
        current_price = data.get("last_price")
        if current_price is None:
            return
        
        logger.info(f"📊 {self.symbol} 当前价格: {current_price:.2f}, 当前系统基准价格: {self.base_price:.2f}")

        # TODO #必须跟交易回调进行绑定。当回调完成,则进行放开下一个绑定逻辑。否则跳过
        if self.entrusted_status :
            logger.info(f"股票代码:{self.symbol},已通过委托下单,等待订单成交,本次不执行委托!")
            return
            

        #当前系统价格小于最低价 或大于最高价
        if current_price > self.up_price or current_price < self.un_price :
            logger.info(f"股票代码:{self.symbol},当前价格:{current_price},脱离价格区间:{self.un_price}到{self.up_price},不再执行网格交易")
            return


        #判断连续买入卖出 大于指定的值 则不进行买卖交易
        # if self.sell_threshold > self.continuous_sell_number and  self.purchase_threshold > self.continuous_purchase_number:
        #     logger.info(f"📊 {self.symbol} 买卖都已达到上限固定次数 禁止交易哦: {current_price:.2f}, 均值: {self.mean_price:.2f}")
        #     return
         

        #判断是否能够满足购买条件
        #计算当前挂单买入价   挂单卖出价 
        current_sell_pice = self.base_price  + self.sell_step_length               #挂单卖出价
        current_purchase_pice = self.base_price - self.purchaseend_step_length     #挂单买入价

        # //todo  
        # 买卖手不超过3手。并且 计算出来的委托价大于等于最低价限制。就执行执行。 

        

        # TODO 同步判断持仓是否够 如果不够是没法卖出的
        if (current_sell_pice <= self.up_price)  and  (self.sell_threshold <= self.continuous_sell_number):
            sale =self.refresh_available_quantity_sale(self.symbol)
            #当前可卖仓位必须要大于当前需要卖出仓位 否则卖失败
            if(sale >= self.sell_size):
                #判断是否满足应该执行策略
                #直接进行卖出 根据股票代码以及当前价格+步长进行卖出
                await self.sell(self.symbol,current_sell_pice )
                #需要自己+1 然后反向操作=0
                self.sell_threshold= self.sell_threshold+1
                self.purchase_threshold= 0

                logger.info(f"📉 卖出信号: {self.symbol} 当前系统价格 {current_price:.2f} , 卖出价格 {current_sell_pice:.2f}")
            else:
                logger.info(f"📉 卖出信号: {self.symbol} 卖出仓位数量:{self.sell_size},当前持仓数量: {sale} ,可卖数量不足,放弃卖出!")
        

            #买手。TODO。同步仓库资金是否足够 不足够 是不能买入的
        if (current_purchase_pice >= self.un_price)  and  (self.purchase_threshold <= self.continuous_purchase_number):
            #判断是否满足应该执行策略
            await self.buy(self.symbol, current_purchase_pice)
            #需要自己+1 然后反向操作=0
            self.sell_threshold= 0
            self.purchase_threshold= self.purchase_threshold +1
            logger.info(f"📈 买入信号: {self.symbol} 当前系统价格 {current_price:.2f} < 购买价格 {current_purchase_pice:.2f}")




        # TODO 需要更新【可选】必须成交后,则按照当前市价进行动态更新值. 
        # if self.last_price is not None:
        #     self.base_price = 0.88

    async def on_stop(self):
        """策略停止回调"""
        logger.info(f"⏹️ 网格策略已停止: {self.strategy_id}")
        # 【可选】保存策略状态